package com.zzyl.nursing.service.impl;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdcardUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.aiinvoker.AiInvoker;
import com.zzyl.nursing.domain.HealthAssessment;
import com.zzyl.nursing.dto.HealthAssessmentDto;
import com.zzyl.nursing.mapper.HealthAssessmentMapper;
import com.zzyl.nursing.service.IHealthAssessmentService;
import com.zzyl.nursing.vo.HealthReportVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * 健康评估Service业务层处理
 *
 * @author mr.luo
 * @date 2025-05-20
 */
@Slf4j
@Service
public class HealthAssessmentServiceImpl extends ServiceImpl<HealthAssessmentMapper, HealthAssessment> implements IHealthAssessmentService {
    @Autowired
    private HealthAssessmentMapper healthAssessmentMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private AiInvoker aiInvoker;

    /**
     * 查询健康评估
     *
     * @param id 健康评估主键
     * @return 健康评估
     */
    @Override
    public HealthAssessment selectHealthAssessmentById(Long id) {
        return getById(id);
    }

    /**
     * 查询健康评估列表
     *
     * @param healthAssessment 健康评估
     * @return 健康评估
     */
    @Override
    public List<HealthAssessment> selectHealthAssessmentList(HealthAssessment healthAssessment) {
        return healthAssessmentMapper.selectHealthAssessmentList(healthAssessment);
    }


    /**
     * 修改健康评估
     *
     * @param healthAssessment 健康评估
     * @return 结果
     */
    @Override
    public int updateHealthAssessment(HealthAssessment healthAssessment) {
        return updateById(healthAssessment) ? 1 : 0;
    }

    /**
     * 批量删除健康评估
     *
     * @param ids 需要删除的健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除健康评估信息
     *
     * @param id 健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentById(Long id) {
        return removeById(id) ? 1 : 0;
    }


    /**
     * 新增健康评估
     *
     * @param healthAssessmentDto
     * @return
     */
    @Override
    public Long addHealthAssessment(HealthAssessmentDto healthAssessmentDto) {
        //对前端传的数据进行校验
        if (!StringUtils.hasLength(healthAssessmentDto.getElderName())) {
            throw new BaseException("老人姓名不能为空");
        }
        if (!StringUtils.hasLength(healthAssessmentDto.getIdCard())) {
            throw new BaseException("身份证号不能为空");
        }
        if (!StringUtils.hasLength(healthAssessmentDto.getPhysicalExamInstitution())) {
            throw new BaseException("体检机构不能为空");
        }
        if (!StringUtils.hasLength(healthAssessmentDto.getPhysicalReportUrl())) {
            throw new BaseException("体检报告URL不能为空");
        }

        //首先，先获得redis中用户的检查报告
        String healthReport = (String) redisTemplate.opsForHash()
                .get(CacheConstants.LOGIN_FILE_KEY, healthAssessmentDto.getIdCard());
        //判断从redis中获取的体检报告是否为空
        if (null == healthReport || !StringUtils.hasLength(healthReport)) {
            throw new BaseException("用户体检报告上传失败");
        }
        //其次获取resources中的体检报告的模板
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("prompt.txt");
        String template = IoUtil.read(inputStream, StandardCharsets.UTF_8);
        //然后给体检报告模板中的占位符进行替换
        String replace = template.replace("prompt", healthReport);
        //调用千帆的接口，对用户的报告进行分析
        String assessmentReport = aiInvoker.AIAssessmentChat(replace);
        //对返回的JSON 数据进行解析
        if (null == assessmentReport || assessmentReport.isEmpty()) {
            throw new BaseException("分析失败，请重新上传资料");
        }
        //将数据插入到健康评估表中
        Long id = saveHealthAssessment(healthAssessmentDto, assessmentReport);
        //删除redis中存储的老人的健康报告
        redisTemplate.opsForHash().delete(CacheConstants.LOGIN_FILE_KEY, healthAssessmentDto.getIdCard());
        //返回体检报告ID
        log.info(healthAssessmentDto.getElderName() + "健康评估成功");
        return id;
    }

    private Long saveHealthAssessment(HealthAssessmentDto healthAssessmentDto, String assessmentReport) {
        HealthAssessment healthAssessment = new HealthAssessment();
        //对assessmentReport进行解析
        HealthReportVo healthReportVo = JSON.parseObject(assessmentReport, HealthReportVo.class);
        //然后对数据进行封装
        String idCard = healthAssessmentDto.getIdCard();
        healthAssessment.setElderName(healthAssessmentDto.getElderName());
        healthAssessment.setIdCard(idCard);
        healthAssessment.setPhysicalExamInstitution(healthAssessmentDto.getPhysicalExamInstitution());
        healthAssessment.setPhysicalReportUrl(healthAssessmentDto.getPhysicalReportUrl());
        healthAssessment.setBirthDate(IdcardUtil.getBirthDate(idCard).toLocalDateTime());
        healthAssessment.setAge(IdcardUtil.getAgeByIdCard(idCard));
        healthAssessment.setGender(IdcardUtil.getGenderByIdCard(idCard) == 0 ? 0 : 1);
        double healthIndex = healthReportVo.getHealthAssessment().getHealthIndex();
        healthAssessment.setHealthScore(String.valueOf(healthIndex));
        healthAssessment.setTotalCheckDate(healthReportVo.getTotalCheckDate());
        healthAssessment.setRiskLevel(healthReportVo.getHealthAssessment().getRiskLevel());
        healthAssessment.setDiseaseRisk(JSON.toJSONString(healthReportVo.getRiskDistribution()));
        healthAssessment.setAbnormalAnalysis(JSON.toJSONString(healthReportVo.getAbnormalData()));
        healthAssessment.setSystemScore(JSON.toJSONString(healthReportVo.getSystemScore()));
        healthAssessment.setSuggestionForAdmission(healthIndex > 60 ? 0 : 1);
        healthAssessment.setNursingLevelName(nursingLevelName(healthIndex));
        healthAssessment.setAssessmentTime(LocalDateTime.now());
        healthAssessment.setReportSummary(healthReportVo.getSummarize());
        boolean save = save(healthAssessment);
        if (!save){
            throw new BaseException("保存失败");
        }
        return healthAssessment.getId();
    }

    private String nursingLevelName(Double healthIndex) {
        if (healthIndex < 0 || healthIndex > 100) {
            throw new BaseException("健康指数不在0-100之间,错误");
        }
        if (healthIndex > 90) {
            return "三级护理";
        } else if (healthIndex > 80) {
            return "二级护理";
        } else if (healthIndex > 70) {
            return "一级护理";
        } else if (healthIndex > 60) {
            return "特级护理";
        } else {
            return "不建议入住";
        }
    }
}
